local util = require "util"
local conf = require "conf"
local require = require
local setmetatable = setmetatable
local error = error
local table = table
local ngx = ngx
local os = os
local string = string
local tonumber = tonumber
local pairs = pairs
package.cpath = "/usr/nginx/?.so;;"
local json = require 'cjson'
module(...)
_VERSION = '0.1'

function  create(user, args)
    local db = conf.get_mysql()
    local sql = "INSERT INTO `battery` SET"

    if args.aid then
        sql = sql .. " aid = " .. args.aid .. ","
    else
        sql = sql .. " aid = " .. user.aid .. ","
    end
    if args.org_id then
        sql = sql .. " org_id = " .. args.org_id .. ","
    else
        sql = sql .. " org_id = " .. user.org_id .. ","
    end

    if args.id then
        sql = sql .. " id = " .. args.id .. ","
    end
    
    if args.model then
        sql = sql .. " model = '" .. args.model .. "',"
    end
    
    if args.comment then
        sql = sql .. " comment = '" .. args.comment .. "',"
    end

    if args.use_count then
        sql = sql .. " use_count = " .. args.use_count .. ","
    end
    if args.use_time then
        sql = sql .. " use_time = " .. args.use_time .. ","
    end
    if args.spoint_id then
        sql = sql .. " spoint_id = " .. args.spoint_id .. ","
    end
    if args.serial_no then
        sql = sql .. " serial_no = " .. args.serial_no .. ","
    end
    if args.name then
        sql = sql .. " name = '" .. args.name .. "',"
    end

    if args.registered_time then
        sql = sql .. " registered_time = " .. args.registered_time .. ","
    end

    sql = sql .. " create_time = " .. os.time() .. ","

    sql = sql .. " update_time = " .. os.time() .. ","
    sql = sql:sub(1, -2)
    ngx.log(ngx.ERR, sql)
    local res = db:query(sql)
    return res
end

function createController(user, args)
    local db = conf.get_mysql()

    local res = create(user, args)
    if not res or res.affected_rows < 1 then
        ngx.print(json.encode({
            err = 1,
            msg = '创建失败'
        }))
        ngx.exit(200)
    else
        local insert_id = res.insert_id
        if insert_id < 1 then
            res = db:query("SELECT LAST_INSERT_ID() AS insert_id")
            if res and res[1] and res[1].insert_id then
                insert_id = res[1].insert_id
            end
        end
        ngx.print(json.encode({
            err = 0,
            id = insert_id,
            msg = '创建成功'
        }))
        ngx.exit(200)
    end 
end

function update(user, args)
    local db = conf.get_mysql()
    local sql = "UPDATE `battery` SET "

    if args.aid then
        sql = sql .. " aid = " .. args.aid .. ","
    end
    if args.org_id then
        sql = sql .. " org_id = " .. args.org_id .. ","
    end

    if args.use_count then
        if args.inc then
            sql = sql .. " use_count = use_count + " .. args.use_count .. ","
        else
            sql = sql .. " use_count = '" .. args.use_count .. "',"
        end
    end

    if args.use_time then
        if args.inc then
            sql = sql .. " use_time = use_time + " .. args.use_time .. ","
            sql = sql .. " use_count = (use_time + " .. args.use_time .. ") / 2160,"
        else
            sql = sql .. " use_time = " .. args.use_time .. ","
        end
    end

    -- if args.id then
    --     sql = sql .. " id = " .. args.id .. ","
    -- end
    
    if args.model then
        sql = sql .. " id = " .. args.model .. ","
    end
    
    if args.comment then 
        sql = sql .. " id = '" .. args.comment .. "',"
    end

    if args.spoint_id then
        sql = sql .. " spoint_id = " .. args.spoint_id .. ","
    end

    if args.charged then
        sql = sql .. " use_count = use_count + " .. 1 .. ","
    end

    if args.serial_no then
        sql = sql .. " serial_no = '" .. args.serial_no .. "',"
    end
    if args.name then
        sql = sql .. " name = '" .. args.name .. "',"
    end

    if args.registered_time then
        sql = sql .. " registered_time = " .. args.registered_time .. ","
    end

    if args.last_use_time then
        sql = sql .. " last_use_time = " .. args.last_use_time .. ","
    end
    sql = sql .. " update_time = " .. os.time() .. ","
    ngx.log(ngx.ERR, sql)
    local res = db:query(sql:sub(1, -2) .. " WHERE id = " .. args.id )
    return res
end

function updateController(user, args)
    if not args.id then
        ngx.print(json.encode({
            err = 2,
            msg = '缺少id'
        }))
    end
    local res = update(user, args)
    if not res or res.affected_rows < 1 then
        ngx.print(json.encode({
            err = 1,
            msg = '更新失败'
        }))
        ngx.exit(200)
    else 
        ngx.print(json.encode({
            err = 0,
            msg = res
        }))
        ngx.exit(200)
    end
end

function delete(user, args)
    local id = args.id
    local db = conf.get_mysql()
    local res = db:query("DELETE FROM `battery` WHERE id = " .. id )
    return res
end

function deleteController(user, args)
    if not args.id then
        ngx.print(json.encode({
            err = 2,
            msg = '缺少id'
        }))
    end
    local res = delete(user, args)
    if not res or res.affected_rows < 1 then
        ngx.print(json.encode({
            err = 1,
            msg = '更新失败'
        }))
        ngx.exit(200)
    else 
        ngx.print(json.encode({
            err = 0,
            msg = res
        }))
        ngx.exit(200)
    end
end

function search(user, args)
    local page_no, page_size, id, name, aid = tonumber(args.page_no), tonumber(args.page_size), args.id, args.name, args.aid
    local db = conf.get_mysql()
    local schedule = require "schedule"
    local plane = require "plane"
    local now  = os.time()

    local sql = "SELECT `battery`.id, `battery`.registered_time, `battery`.aid, `battery`.org_id, `battery`.use_time,`battery`.use_count, `battery`.serial_no, `battery`.spoint_id, `battery_model`.lifespan, `battery_model`.manufacturer, `battery`.comment, `battery`.model, `battery_model`.suggest_charge_current," .. 

    "`battery_model`.discharge_rate, `battery_model`.max_discharge_rate, `battery_model`.discharge_current, `battery_model`.charge_end_volt,`battery_model`.size, `battery_model`.weight,`battery_model`.bundle_count, `battery_model`.capacity, `battery`.create_time, `battery`.last_use_time, `area`.name as area, `spoint`.name as sname, `organization`.name_show as organization" ..

    " FROM `battery` left join `area` on `area`.id = battery.aid left join `organization` on `organization`.id = `battery`.org_id left join `spoint` on  `spoint`.id = `battery`.spoint_id left join `battery_model` on `battery_model`.id = `battery`.model WHERE 1=1";
    if name then
        sql = sql .. " AND `battery`.name like '%" .. name .. "%'"
    end

    if aid then
        local ids = conf.get_aids(tonumber(aid))
        sql = sql .. " AND `battery`.aid in (" ..  table.concat(ids, ",") .. ")"
    end

    if args.org_id then
        local ids = conf.get_orgIds(tonumber(args.org_id))
        sql = sql .. " AND `battery`.org_id in (" ..  table.concat(ids, ",") .. ")"
    end

    if id then
        sql = sql .. " AND `battery`.id = " .. id
    end

    if args.spoint_id then
        sql = sql .. " AND `battery`.spoint_id = " .. args.spoint_id
    end

    if args.use_count_start then
        sql = sql .. " AND `battery`.use_count >= " .. args.use_count_start
    end

    if args.remain_count_start then
        sql = sql .. " AND (`battery_model`.lifespan - `battery`.use_count) >= " .. args.remain_count_start
    end

    if args.remain_count_end then
        sql = sql .. " AND (`battery_model`.lifespan - `battery`.use_count) <= " .. args.remain_count_end
    end

    if args.use_count_end then
        sql = sql .. " AND `battery`.use_count <= " .. args.use_count_end
    end

    if args.serial_no then
        sql = sql .. " AND `battery`.serial_no = " .. args.serial_no
    end

    sql = sql .. " AND `battery`.aid in (" ..  table.concat(user.aids, ",") .. ")"

    sql = sql .. " AND `battery`.org_id in (" ..  table.concat(user.orgIds, ",") .. ")"

    ngx.log(ngx.ERR, sql)
    local count = #(db:query(sql) or {})

    if page_no and page_size then
        sql = sql ..  " LIMIT " .. (page_no * page_size) .. "," .. page_size
    end
    local res = db:query(sql)
    ngx.log(ngx.ERR, json.encode(res))
    return res,count
end

function searchController(user, args)
    local res, count = search(user, args)
    if not res or #res == 0 then
       createController(user,args)
    else
        ngx.print(json.encode({
            err = 0,
            msg = res,
            count = count
        }))
        ngx.exit(200)
    end
end

function getModel(user, args)
    local db = conf.get_mysql()
    local sql = "SELECT * FROM battery_model WHERE 1=1"
    if args.id then
        sql = sql .. " AND id = " .. args.id 
    end
    local res = db:query(sql)
    if not res then
        ngx.print(json.encode({
            err = 1,
            msg = '未找到相应的电池类型'
        }))
        ngx.exit(200)
    else
        ngx.print(json.encode({
            err = 0,
            msg = res
        }))
        ngx.exit(200)
    end
end

function default(args)
    local user = conf.parse_token(args, "spoint")
    if args.action == 'create' then
        createController(user, args)
    elseif args.action == 'update' then
        updateController(user, args)
    elseif args.action == 'search' then
        searchController(user, args)
    elseif args.action == 'delete' then
        deleteController(user, args)
    elseif args.action == 'getModel' then
        getModel(user, args)
    end
end

local class_mt = {
    __newindex = function (table, key, val)
        error('attempt to write to undeclared variable "' .. key .. '"')
    end
}
setmetatable(_M, class_mt)
